package dao;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Date;

import bo.Cliente;
import exception.DataException;
import exception.DatabaseConnectException;
import exception.EmptyResultException;

public class ClienteDAO {

	public ArrayList<Cliente> consultaTodosRegistros() throws DataException,
			EmptyResultException, SQLException, DatabaseConnectException {

		ArrayList<Cliente> clientes = null;
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;

		try {
			preparedStatement = Conexao
					.getInst()
					.getConnection()
					.prepareStatement(
							"SELECT cliente.id, " + "cliente.nome, "
									+ "cliente.sobrenome, "
									+ "cliente.tipo_pessoa, "
									+ "cliente.email, "
									+ "cliente.data_nascimento, "
									+ "cliente.telefone, " + "cliente.cep, "
									+ "cliente.endereco, "
									+ "cliente.complemento, "
									+ "cliente.numero, "
									+ "cliente.apartamento, "
									+ "cliente.bloco, " + "cliente.edificio, "
									+ "cliente.id_cidade, "
									+ "cliente.bairro, " + "cliente.sexo, "
									+ "cliente.cpf, " + "cliente.rg, "
									+ "cliente.razao_social, "
									+ "cliente.cnpj, "
									+ "cliente.insc_municipal, "
									+ "cliente.insc_estadual, "
									+ "cliente.observacao, "
									+ "cliente.celular " + "FROM cliente "
									+ "ORDER BY cliente.id;");

			resultSet = preparedStatement.executeQuery();

			clientes = new ArrayList<Cliente>();
			while (resultSet.next()) {
				Cliente cliente = new Cliente();
				cliente.setId(resultSet.getInt(1));
				cliente.setNome(resultSet.getString(2));
				cliente.setSobrenome(resultSet.getString(3));
				cliente.setTipoPessoa(resultSet.getString(4));
				cliente.setEmail(resultSet.getString(5));
				cliente.setDataNascimento(resultSet.getDate(6));
				cliente.setTelefone(resultSet.getString(7));
				cliente.setCep(resultSet.getString(8));
				cliente.setEndereco(resultSet.getString(9));
				cliente.setComplemento(resultSet.getString(10));
				cliente.setNumero(resultSet.getInt(11));
				cliente.setApartamento(resultSet.getString(12));
				cliente.setBloco(resultSet.getString(13));
				cliente.setEdificio(resultSet.getString(14));
				cliente.setIdCidade(resultSet.getInt(15));
				cliente.setBairro(resultSet.getString(16));
				cliente.setSexo(resultSet.getString(17));
				cliente.setCpf(resultSet.getString(18));
				cliente.setRg(resultSet.getString(19));
				cliente.setRazaoSocial(resultSet.getString(20));
				cliente.setCnpj(resultSet.getString(21));
				cliente.setInscMunic(resultSet.getString(22));
				cliente.setInscEstad(resultSet.getString(23));
				cliente.setObservacao(resultSet.getString(24));
				cliente.setCelular(resultSet.getString(25));
				clientes.add(cliente);
			}

			if (clientes.isEmpty()) {
				throw new EmptyResultException();
			}

		} catch (SQLException e) {
			throw new DataException(e, DataException.SELECT);
		} finally {
			preparedStatement.close();
			resultSet.close();
		}

		return clientes;

	}

	public ArrayList<Cliente> consultaPorId(Integer id)
			throws DatabaseConnectException, DataException, SQLException,
			EmptyResultException {

		ArrayList<Cliente> clientes = null;
		ResultSet resultSet = null;
		PreparedStatement preparedStatement = null;

		try {
			preparedStatement = Conexao
					.getInst()
					.getConnection()
					.prepareStatement(
							"SELECT cliente.id, " + "cliente.nome, "
									+ "cliente.sobrenome, "
									+ "cliente.tipo_pessoa, "
									+ "cliente.email, "
									+ "cliente.data_nascimento, "
									+ "cliente.telefone, " + "cliente.cep, "
									+ "cliente.endereco, "
									+ "cliente.complemento, "
									+ "cliente.numero, "
									+ "cliente.apartamento, "
									+ "cliente.bloco, " + "cliente.edificio, "
									+ "cliente.id_cidade, "
									+ "cliente.bairro, " + "cliente.sexo, "
									+ "cliente.cpf, " + "cliente.rg, "
									+ "cliente.razao_social, "
									+ "cliente.cnpj, "
									+ "cliente.insc_municipal, "
									+ "cliente.insc_estadual, "
									+ "cliente.observacao, "
									+ "cliente.celular FROM cliente "
									+ "WHERE cliente.id = ? "
									+ "ORDER BY cliente.id;");

			preparedStatement.setInt(1, id);

			resultSet = preparedStatement.executeQuery();

			clientes = new ArrayList<Cliente>();

			while (resultSet.next()) {
				Cliente cliente = new Cliente();
				cliente.setId(resultSet.getInt(1));
				cliente.setNome(resultSet.getString(2));
				cliente.setSobrenome(resultSet.getString(3));
				cliente.setTipoPessoa(resultSet.getString(4));
				cliente.setEmail(resultSet.getString(5));
				cliente.setDataNascimento(resultSet.getDate(6));
				cliente.setTelefone(resultSet.getString(7));
				cliente.setCep(resultSet.getString(8));
				cliente.setEndereco(resultSet.getString(9));
				cliente.setComplemento(resultSet.getString(10));
				cliente.setNumero(resultSet.getInt(11));
				cliente.setApartamento(resultSet.getString(12));
				cliente.setBloco(resultSet.getString(13));
				cliente.setEdificio(resultSet.getString(14));
				cliente.setIdCidade(resultSet.getInt(15));
				cliente.setBairro(resultSet.getString(16));
				cliente.setSexo(resultSet.getString(17));
				cliente.setCpf(resultSet.getString(18));
				cliente.setRg(resultSet.getString(19));
				cliente.setRazaoSocial(resultSet.getString(20));
				cliente.setCnpj(resultSet.getString(21));
				cliente.setInscMunic(resultSet.getString(22));
				cliente.setInscEstad(resultSet.getString(23));
				cliente.setObservacao(resultSet.getString(24));
				cliente.setCelular(resultSet.getString(25));
				clientes.add(cliente);
			}

			if (clientes.isEmpty()) {
				throw new EmptyResultException();
			}

		} catch (SQLException e) {
			throw new DataException(e, DataException.SELECT);
		} finally {
			preparedStatement.close();
			resultSet.close();
		}

		return clientes;
	}

	public ArrayList<Cliente> consultaPorNome(String nome)
			throws DatabaseConnectException, DataException, SQLException,
			EmptyResultException {

		ArrayList<Cliente> clientes = null;
		ResultSet resultSet = null;
		PreparedStatement preparedStatement = null;

		try {
			preparedStatement = Conexao
					.getInst()
					.getConnection()
					.prepareStatement(
							"SELECT cliente.id, " + "cliente.nome, "
									+ "cliente.sobrenome, "
									+ "cliente.tipo_pessoa, "
									+ "cliente.email, "
									+ "cliente.data_nascimento, "
									+ "cliente.telefone, " + "cliente.cep, "
									+ "cliente.endereco, "
									+ "cliente.complemento, "
									+ "cliente.numero, "
									+ "cliente.apartamento, "
									+ "cliente.bloco, " + "cliente.edificio, "
									+ "cliente.id_cidade, "
									+ "cliente.bairro, " + "cliente.sexo, "
									+ "cliente.cpf, " + "cliente.rg, "
									+ "cliente.razao_social, "
									+ "cliente.cnpj, "
									+ "cliente.insc_municipal, "
									+ "cliente.insc_estadual, "
									+ "cliente.observacao, "
									+ "cliente.celular " + "FROM cliente "
									+ "WHERE cliente.nome = ?"
									+ "ORDER BY cliente.nome;");

			preparedStatement.setString(1, nome);

			resultSet = preparedStatement.executeQuery();

			clientes = new ArrayList<Cliente>();
			while (resultSet.next()) {
				Cliente cliente = new Cliente();
				cliente.setId(resultSet.getInt(1));
				cliente.setNome(resultSet.getString(2));
				cliente.setSobrenome(resultSet.getString(3));
				cliente.setTipoPessoa(resultSet.getString(4));
				cliente.setEmail(resultSet.getString(5));
				cliente.setDataNascimento(resultSet.getDate(6));
				cliente.setTelefone(resultSet.getString(7));
				cliente.setCep(resultSet.getString(8));
				cliente.setEndereco(resultSet.getString(9));
				cliente.setComplemento(resultSet.getString(10));
				cliente.setNumero(resultSet.getInt(11));
				cliente.setApartamento(resultSet.getString(12));
				cliente.setBloco(resultSet.getString(13));
				cliente.setEdificio(resultSet.getString(14));
				cliente.setIdCidade(resultSet.getInt(15));
				cliente.setBairro(resultSet.getString(16));
				cliente.setSexo(resultSet.getString(17));
				cliente.setCpf(resultSet.getString(18));
				cliente.setRg(resultSet.getString(19));
				cliente.setRazaoSocial(resultSet.getString(20));
				cliente.setCnpj(resultSet.getString(21));
				cliente.setInscMunic(resultSet.getString(22));
				cliente.setInscEstad(resultSet.getString(23));
				cliente.setObservacao(resultSet.getString(24));
				cliente.setCelular(resultSet.getString(25));
				clientes.add(cliente);
			}

			if (clientes.isEmpty()) {
				throw new EmptyResultException();
			}

		} catch (SQLException e) {
			throw new DataException(e, DataException.SELECT);
		} finally {
			preparedStatement.close();
			resultSet.close();
		}

		return clientes;
	}

	public ArrayList<Cliente> consultaPorDataNascimento(Date dataNascimento)
			throws DatabaseConnectException, DataException, SQLException,
			EmptyResultException {

		ArrayList<Cliente> clientes = null;
		ResultSet resultSet = null;
		PreparedStatement preparedStatement = null;

		try {
			preparedStatement = Conexao
					.getInst()
					.getConnection()
					.prepareStatement(
							"SELECT cliente.id, " + "cliente.nome, "
									+ "cliente.sobrenome, "
									+ "cliente.tipo_pessoa, "
									+ "cliente.email, "
									+ "cliente.data_nascimento, "
									+ "cliente.telefone, " + "cliente.cep, "
									+ "cliente.endereco, "
									+ "cliente.complemento, "
									+ "cliente.numero, "
									+ "cliente.apartamento, "
									+ "cliente.bloco, " + "cliente.edificio, "
									+ "cliente.id_cidade, "
									+ "cliente.bairro, " + "cliente.sexo, "
									+ "cliente.cpf, " + "cliente.rg, "
									+ "cliente.razao_social, "
									+ "cliente.cnpj, "
									+ "cliente.insc_municipal, "
									+ "cliente.insc_estadual, "
									+ "cliente.observacao, "
									+ "cliente.celular " + "FROM cliente "
									+ "WHERE cliente.data_nascimento = ?"
									+ "ORDER BY cliente.data_nascimento;");

			preparedStatement.setDate(1,
					new java.sql.Date(dataNascimento.getTime()));

			resultSet = preparedStatement.executeQuery();

			clientes = new ArrayList<Cliente>();
			while (resultSet.next()) {
				Cliente cliente = new Cliente();
				cliente.setId(resultSet.getInt(1));
				cliente.setNome(resultSet.getString(2));
				cliente.setSobrenome(resultSet.getString(3));
				cliente.setTipoPessoa(resultSet.getString(4));
				cliente.setEmail(resultSet.getString(5));
				cliente.setDataNascimento(resultSet.getDate(6));
				cliente.setTelefone(resultSet.getString(7));
				cliente.setCep(resultSet.getString(8));
				cliente.setEndereco(resultSet.getString(9));
				cliente.setComplemento(resultSet.getString(10));
				cliente.setNumero(resultSet.getInt(11));
				cliente.setApartamento(resultSet.getString(12));
				cliente.setBloco(resultSet.getString(13));
				cliente.setEdificio(resultSet.getString(14));
				cliente.setIdCidade(resultSet.getInt(15));
				cliente.setBairro(resultSet.getString(16));
				cliente.setSexo(resultSet.getString(17));
				cliente.setCpf(resultSet.getString(18));
				cliente.setRg(resultSet.getString(19));
				cliente.setRazaoSocial(resultSet.getString(20));
				cliente.setCnpj(resultSet.getString(21));
				cliente.setInscMunic(resultSet.getString(22));
				cliente.setInscEstad(resultSet.getString(23));
				cliente.setObservacao(resultSet.getString(24));
				cliente.setCelular(resultSet.getString(25));
				clientes.add(cliente);
			}

			if (clientes.isEmpty()) {
				throw new EmptyResultException();
			}

		} catch (SQLException e) {
			throw new DataException(e, DataException.SELECT);
		} finally {
			preparedStatement.close();
			resultSet.close();
		}

		return clientes;
	}

	public ArrayList<Cliente> consultaPorSobrenome(String sobrenome)
			throws DatabaseConnectException, DataException, SQLException,
			EmptyResultException {

		ArrayList<Cliente> clientes = null;
		ResultSet resultSet = null;
		PreparedStatement preparedStatement = null;

		try {
			preparedStatement = Conexao
					.getInst()
					.getConnection()
					.prepareStatement(
							"SELECT cliente.id, " + "cliente.nome, "
									+ "cliente.sobrenome, "
									+ "cliente.tipo_pessoa, "
									+ "cliente.email, "
									+ "cliente.data_nascimento, "
									+ "cliente.telefone, " + "cliente.cep, "
									+ "cliente.endereco, "
									+ "cliente.complemento, "
									+ "cliente.numero, "
									+ "cliente.apartamento, "
									+ "cliente.bloco, " + "cliente.edificio, "
									+ "cliente.id_cidade, "
									+ "cliente.bairro, " + "cliente.sexo, "
									+ "cliente.cpf, " + "cliente.rg, "
									+ "cliente.razao_social, "
									+ "cliente.cnpj, "
									+ "cliente.insc_municipal, "
									+ "cliente.insc_estadual, "
									+ "cliente.observacao, "
									+ "cliente.celular " + "FROM cliente "
									+ "WHERE cliente.sobrenome = ?"
									+ "ORDER BY cliente.sobrenome;");

			preparedStatement.setString(1, sobrenome);

			resultSet = preparedStatement.executeQuery();

			clientes = new ArrayList<Cliente>();
			while (resultSet.next()) {
				Cliente cliente = new Cliente();
				cliente.setId(resultSet.getInt(1));
				cliente.setNome(resultSet.getString(2));
				cliente.setSobrenome(resultSet.getString(3));
				cliente.setTipoPessoa(resultSet.getString(4));
				cliente.setEmail(resultSet.getString(5));
				cliente.setDataNascimento(resultSet.getDate(6));
				cliente.setTelefone(resultSet.getString(7));
				cliente.setCep(resultSet.getString(8));
				cliente.setEndereco(resultSet.getString(9));
				cliente.setComplemento(resultSet.getString(10));
				cliente.setNumero(resultSet.getInt(11));
				cliente.setApartamento(resultSet.getString(12));
				cliente.setBloco(resultSet.getString(13));
				cliente.setEdificio(resultSet.getString(14));
				cliente.setIdCidade(resultSet.getInt(15));
				cliente.setBairro(resultSet.getString(16));
				cliente.setSexo(resultSet.getString(17));
				cliente.setCpf(resultSet.getString(18));
				cliente.setRg(resultSet.getString(19));
				cliente.setRazaoSocial(resultSet.getString(20));
				cliente.setCnpj(resultSet.getString(21));
				cliente.setInscMunic(resultSet.getString(22));
				cliente.setInscEstad(resultSet.getString(23));
				cliente.setObservacao(resultSet.getString(24));
				cliente.setCelular(resultSet.getString(25));
				clientes.add(cliente);
			}

			if (clientes.isEmpty()) {
				throw new EmptyResultException();
			}

		} catch (SQLException e) {
			throw new DataException(e, DataException.SELECT);
		} finally {
			preparedStatement.close();
			resultSet.close();
		}

		return clientes;
	}

	public void incluir(Cliente cliente) throws DataException,
			DatabaseConnectException {
		PreparedStatement preparedStatement = null;

		try {
			preparedStatement = Conexao
					.getInst()
					.getConnection()
					.prepareStatement(
							"INSERT INTO cliente(id, nome, sobrenome, "
									+ "tipo_pessoa, email, data_nascimento, "
									+ "telefone, cep, endereco, complemento, "
									+ "numero, apartamento, bloco, edificio,"
									+ "id_cidade, bairro, sexo, cpf, rg, razao_social, cnpj, insc_municipal,"
									+ "insc_estadual, observacao, celular)"
									+ "VALUES (nextval('seqcliente'), ?, ?, ?, ?, ?, ?,"
									+ "?, ?, ?, ?, ?, ?, ?,"
									+ "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");

			preparedStatement.setString(1, cliente.getNome());
			preparedStatement.setString(2, cliente.getSobrenome());
			preparedStatement.setString(3, cliente.getTipoPessoa());
			preparedStatement.setString(4, cliente.getEmail());
			if (cliente.getDataNascimento() != null) {
				preparedStatement.setDate(5, new java.sql.Date(cliente
						.getDataNascimento().getTime()));
			} else {
				preparedStatement.setNull(5, Types.DATE);
			}
			preparedStatement.setString(6, cliente.getTelefone());
			preparedStatement.setString(7, cliente.getCep());
			preparedStatement.setString(8, cliente.getEndereco());
			preparedStatement.setString(9, cliente.getComplemento());
			preparedStatement.setInt(10, cliente.getNumero());
			preparedStatement.setString(11, cliente.getApartamento());
			preparedStatement.setString(12, cliente.getBloco());
			preparedStatement.setString(13, cliente.getEdificio());
			preparedStatement.setInt(14, cliente.getIdCidade());
			preparedStatement.setString(15, cliente.getBairro());
			preparedStatement.setString(16, cliente.getSexo());
			preparedStatement.setString(17, cliente.getCpf());
			preparedStatement.setString(18, cliente.getRg());
			preparedStatement.setString(19, cliente.getRazaoSocial());
			preparedStatement.setString(20, cliente.getCnpj());
			preparedStatement.setString(21, cliente.getInscMunic());
			preparedStatement.setString(22, cliente.getInscEstad());
			preparedStatement.setString(23, cliente.getObservacao());
			preparedStatement.setString(24, cliente.getCelular());

			preparedStatement.executeUpdate();

		} catch (SQLException e) {
			throw new DataException(e, DataException.INSERT);
		}
	}

	public void alterar(Cliente cliente) throws DataException,
			DatabaseConnectException {
		PreparedStatement preparedStatement = null;

		try {
			preparedStatement = Conexao
					.getInst()
					.getConnection()
					.prepareStatement(
							"UPDATE cliente "
									+ "SET nome=?, sobrenome=?, tipo_pessoa=?, email=?, data_nascimento=?,"
									+ " telefone=?, cep=?, endereco=?, complemento=?, numero=?, apartamento=?,"
									+ " bloco=?, edificio=?, id_cidade=?, bairro=?, sexo=?, cpf=?, rg=?,"
									+ " razao_social=?, cnpj=?, insc_municipal=?, insc_estadual=?, observacao=?,"
									+ " celular=?" + "WHERE cliente.id=?");

			preparedStatement.setString(1, cliente.getNome());
			preparedStatement.setString(2, cliente.getSobrenome());
			preparedStatement.setString(3, cliente.getTipoPessoa());
			preparedStatement.setString(4, cliente.getEmail());
			if (cliente.getDataNascimento() != null) {
				preparedStatement.setDate(5, new java.sql.Date(cliente
						.getDataNascimento().getTime()));
			} else {
				preparedStatement.setNull(5, Types.DATE);
			}
			preparedStatement.setString(6, cliente.getTelefone());
			preparedStatement.setString(7, cliente.getCep());
			preparedStatement.setString(8, cliente.getEndereco());
			preparedStatement.setString(9, cliente.getComplemento());
			preparedStatement.setInt(10, cliente.getNumero());
			preparedStatement.setString(11, cliente.getApartamento());
			preparedStatement.setString(12, cliente.getBloco());
			preparedStatement.setString(13, cliente.getEdificio());
			preparedStatement.setInt(14, cliente.getIdCidade());
			preparedStatement.setString(15, cliente.getBairro());
			preparedStatement.setString(16, cliente.getSexo());
			preparedStatement.setString(17, cliente.getCpf());
			preparedStatement.setString(18, cliente.getRg());
			preparedStatement.setString(19, cliente.getRazaoSocial());
			preparedStatement.setString(20, cliente.getCnpj());
			preparedStatement.setString(21, cliente.getInscMunic());
			preparedStatement.setString(22, cliente.getInscEstad());
			preparedStatement.setString(23, cliente.getObservacao());
			preparedStatement.setString(24, cliente.getCelular());
			preparedStatement.setInt(25, cliente.getId());

			preparedStatement.executeUpdate();

		} catch (SQLException e) {
			throw new DataException(e, DataException.UPDATE);
		}
	}

	public void excluir(Integer id) throws DataException,
			DatabaseConnectException {
		PreparedStatement preparedStatement = null;

		try {
			preparedStatement = Conexao
					.getInst()
					.getConnection()
					.prepareStatement(
							"DELETE FROM cliente WHERE cliente.id = ?");

			preparedStatement.setInt(1, id);

			preparedStatement.executeUpdate();

		} catch (SQLException e) {
			throw new DataException(e, DataException.DELETE);
		}
	}

}
